using System;
using System.Data;
using System.Web;
using System.Collections;

using BEGDC.CC.Entity;
using BEGDC.CC.BL.Workflow;
using BEGDC.CC.BL.Common;
using BEGDC.CC.BL.UserManagement;
using BEGDC.Utility.Castle;
using BEGDC.Utility.ExceptionManagement;
using NHibernate;
using Castle.Services.Transaction;
using Castle.Facilities.NHibernateIntegration;

namespace BEGDC.CC.BL.CCFlow.ECSCV
{
	/// <summary>
	/// Summary description for CVService.
	/// </summary>
	[Transactional]
	public class ECSCVService: IECSCV
	{
		private ISessionManager _sessionManager;
		private ECSCVFlow _flowInstance;

		public ECSCVService(ISessionManager sessionManager)
		{
			this._sessionManager = sessionManager;
		}

		public ECSCVService()
		{
			//
			// TODO: Add constructor logic here
			//
		}

		public FlowBase GetFlowInstance
		{
			get
			{
				if(_flowInstance == null)
					_flowInstance = new ECSCVFlow();
				return _flowInstance;
			}
		}

		[Transaction(TransactionMode.Requires)]
		public void Request(Application app)
		{
			if( app == null )	return;
	
			using(ISession session = _sessionManager.OpenSession())
			{
				try
				{
					app.AppNo = this.GenerateAppNo(false, app, true);
					app.RequestDate = System.DateTime.Now;
					session.Update(app);
						
					FlowInstance flowinstance = this.GetFlowInstance.GetApplicationFlow(session, app.Id);
					if(flowinstance==null)
					{
						flowinstance = new BEGDC.CC.Entity.FlowInstance();
						flowinstance.FlowID = this.GetFlowInstance.Start();
						this.GetFlowInstance.SaveFlowInstance(session, app, flowinstance, SysDicItem.ProjectStatusFlag.NORMAL,WorkTransition.ECSCV_Apply,WorkTransition.ECSCV_Apply);
						this.GetFlowInstance.InitializeProjectMember(session, app.Id);
					}
					else
					{
						this.GetFlowInstance.SaveFlowInstance(session, app, flowinstance, SysDicItem.ProjectStatusFlag.NORMAL,WorkTransition.ECSCV_Apply,WorkTransition.ECSCV_Apply);
					}

					IUtility utiService = AppContainer.Instance[ServiceConst.UtilityService] as IUtility;
					int typeId = utiService.GetDicItemID(app.ApplicationType, BEGDC.CC.BL.Common.DicType.Application_Type);
					int stepId;

					string CostCenterHead = string.Empty;
					string DepartmentFNC = string.Empty;
					string SSMEHead = string.Empty;
					FlowMember member;

					if(app.IsSSME)
					{
						CostCenterHead = this.GetFlowInstance.GetCostCenterHeadByCostCenter(session, app.CostCenterCode.DicItemKey);
						SSMEHead = this.GetFlowInstance.GetSSMEHead(session);
					}
					else
						DepartmentFNC = this.GetFlowInstance.GetDepartmentFNCByDepartment(session, app.DepartmentType.DicItemKey);
					

					if(CostCenterHead != string.Empty)
					{
						stepId = utiService.QueryStepByCode(WorkTransition.ECSCV_CostCenterHeadApproval, typeId).Id;
						member = this.GetFlowInstance.GetFlowMemberByAppStep(session, app.Id, stepId);
						if(member != null)
						{
							member.Employee = new Employee();
							member.Employee.Id = CostCenterHead;
							session.Update( member, member.Id );
						}
					}

					if(DepartmentFNC != string.Empty)
					{
						stepId = utiService.QueryStepByCode(WorkTransition.ECSCV_DepartmentFNCApproval, typeId).Id;
						member = this.GetFlowInstance.GetFlowMemberByAppStep(session, app.Id, stepId);
						if(member != null)
						{
							member.Employee = new Employee();
							member.Employee.Id = DepartmentFNC;
							session.Update( member, member.Id );
						}
					}

					if(SSMEHead != string.Empty)
					{
						stepId = utiService.QueryStepByCode(WorkTransition.ECSCV_SSMEEVPApproval, typeId).Id;
						member = this.GetFlowInstance.GetFlowMemberByAppStep(session, app.Id, stepId);
						if(member != null)
						{
							member.Employee = new Employee();
							member.Employee.Id = SSMEHead;
							session.Update( member, member.Id );
						}
					}
					
					PerformWorkflow(flowinstance.FlowID, BEGDC.CC.BL.Workflow.WorkTransition.Submit, string.Empty);
				}
				catch(Exception ex)
				{
					CCS.Utility.LogAccess.WriteErrLog( ex.StackTrace, ex.Message );throw ex;
				}
				finally
				{
					session.Close();
				}
			}
		}
		private Nullables.NullableDateTime GetAppRequestDate(int appID)
		{
		
			BEGDC.CC.BL.Common.Query.IQuery queryService= AppContainer.Instance[ServiceConst.QueryService] as BEGDC.CC.BL.Common.Query.IQuery;
			return queryService.GetAppRequestDate(appID);

		}

		[Transaction(TransactionMode.Requires)]
		public void Save(Application app, CustomerInfo customer, BusinessPurpose business, Topic topic, SalesTeamInfo salesInfo, 
			LogisticalInfo logist, PaymentInfo payment, IList customerAttendee, IList alAttendee, IList sites, IList cost, IList contract)
		{
			if( app == null )	return;

			if (app.Id>0)
			{
				if (app.RequestDate==Nullables.NullableDateTime.Default)
				{
					Nullables.NullableDateTime date=GetAppRequestDate(app.Id);

					if (date !=Nullables.NullableDateTime.Default)
					{
						app.RequestDate =date;
					}
				}		
			}
			using(ISession session = _sessionManager.OpenSession())
			{
				try
				{
					app.AppNo = this.GenerateAppNo(true, app, false);
					if (app.Id > 0)
					{
				


						session.Update(app);
						customer.Application = app;
						business.Application = app;
						topic.Application = app;
						salesInfo.Application = app;
						logist.Application = app;
						payment.Application = app;
						session.Update(customer);
						session.Update(business);
						session.Update(topic);
						session.Update(salesInfo);
						session.Update(logist);
						session.Update(payment);
						
						session.Delete("from CustomerAttendee where CustomerInfoID="+customer.Id);
						for(int i=0; i<customerAttendee.Count; i++)
						{
							CustomerAttendee cus = (CustomerAttendee)customerAttendee[i];
							cus.CustomerInfo = customer;
							session.Save(cus);
						}
						session.Delete("from ALAttendee where AppID="+app.Id);
						for(int i=0; i<alAttendee.Count; i++)
						{
							ALAttendee al = (ALAttendee)alAttendee[i];
							al.Application = app;
							session.Save(al);
						}
						session.Delete("from AppVisitingSite where AppID="+app.Id);
						for(int i=0; i<sites.Count; i++)
						{
							AppVisitingSite site = (AppVisitingSite)sites[i];
							site.Application = app;
							session.Save(site);
						}
						session.Delete("from CostCenterRelatedCost where PaymentInfoID="+payment.Id);//+" and costtype="+CostType.Budget);
						for(int i=0; i<cost.Count; i++)
						{
							CostCenterRelatedCost co = (CostCenterRelatedCost)cost[i];
							co.PaymentInfo = payment;
							session.Save(co);
						}
						session.Delete("from ContractInfo where AppID="+app.Id);
						for(int i=0; i<contract.Count; i++)
						{
							ContractInfo ci = (ContractInfo)contract[i];
							ci.Application = app;
							session.Save(ci);
						}
					}
					else
					{
						session.Save(app);
						customer.Application = app;
						business.Application = app;
						topic.Application = app;
						salesInfo.Application = app;
						logist.Application = app;
						payment.Application = app;
						session.Save(customer);
						session.Save(business);
						session.Save(topic);
						session.Save(salesInfo);
						session.Save(logist);
						session.Save(payment);
						
						for(int i=0; i<customerAttendee.Count; i++)
						{
							CustomerAttendee cus = (CustomerAttendee)customerAttendee[i];
							cus.CustomerInfo = customer;
							session.Save(cus);
						}
						for(int i=0; i<alAttendee.Count; i++)
						{
							ALAttendee al = (ALAttendee)alAttendee[i];
							al.Application = app;
							session.Save(al);
						}
						for(int i=0; i<sites.Count; i++)
						{
							AppVisitingSite site = (AppVisitingSite)sites[i];
							site.Application = app;
							session.Save(site);
						}
						for(int i=0; i<cost.Count; i++)
						{
							CostCenterRelatedCost co = (CostCenterRelatedCost)cost[i];
							co.PaymentInfo = payment;
							session.Save(co);
						}
						for(int i=0; i<contract.Count; i++)
						{
							ContractInfo ci = (ContractInfo)contract[i];
							ci.Application = app;
							session.Save(ci);
						}
					}
				}
				catch(Exception ex)
				{
					CCS.Utility.LogAccess.WriteErrLog( ex.StackTrace, ex.Message );throw ex;
				}
				finally
				{
					session.Close();
				}
			}
		}

		[Transaction(TransactionMode.Requires)]
		public void Assign(long flowID, string nextTransition, string employeeNo, int appID, string comment)
		{
			using(ISession session = _sessionManager.OpenSession())
			{
				if(nextTransition == CVTransitionList.Assign)
				{
					FlowMember member = this.GetFlowInstance.GetFlowMemberByAppStep(session, appID, WorkTransition.ECSCV_Check, FlowTypes.ECSCV);
					member.Employee = new Employee();
					member.Employee.Id = employeeNo;
					session.Update( member, member.Id );

					member = this.GetFlowInstance.GetFlowMemberByAppStep(session, appID, WorkTransition.ECSCV_Close, FlowTypes.ECSCV);
					member.Employee = new Employee();
					member.Employee.Id = employeeNo;
					session.Update( member, member.Id );
				}
				PerformWorkflow(flowID, nextTransition, comment);
			}
		}

		[Transaction(TransactionMode.Requires)]
		public void Check(long flowID, string nextTransition, string comment)
		{
			using(ISession session = _sessionManager.OpenSession())
			{
				FlowInstance instance = this.GetFlowInstance.QueryFlowInstance(session, flowID);
				if(instance.CurrentStep.StepName == WorkTransition.ECSCV_Assignment)
				{
					if(nextTransition == ECSCVTransitionList.Check)
					{
						FlowMember member = this.GetFlowInstance.GetFlowMemberByAppStep(session, instance.Application.Id, WorkTransition.ECSCV_Check, FlowTypes.ECSCV);
						member.Employee = new Employee();
						member.Employee.Id = ((CCIdentity)HttpContext.Current.User.Identity).UserInfo.Id;
						session.Update( member, member.Id );

						member = this.GetFlowInstance.GetFlowMemberByAppStep(session, instance.Application.Id, WorkTransition.ECSCV_Close, FlowTypes.ECSCV);
						member.Employee = new Employee();
						member.Employee.Id = ((CCIdentity)HttpContext.Current.User.Identity).UserInfo.Id;
						session.Update( member, member.Id );
					}
				}
			}
			PerformWorkflow(flowID, nextTransition, comment);
		}

		[Transaction(TransactionMode.Requires)]
		public void ReAssign(long flowID, string employeeNo)
		{
			using(ISession session = _sessionManager.OpenSession())
			{
				FlowInstance instance = this.GetFlowInstance.QueryFlowInstance(session, flowID);
				
				FlowMember member = this.GetFlowInstance.GetFlowMemberByAppStep(session, instance.Application.Id, WorkTransition.ECSCV_Check, FlowTypes.ECSCV);
				if(member.Employee != null)
				{
					if(member.Employee.Id == instance.CurrentActiveOwner)
						instance.CurrentActiveOwner = employeeNo;
					if(member.Employee.Id == instance.CurrentOwner)
						instance.CurrentOwner = employeeNo;
					session.Update( instance, instance.Id );
				}
				member.Employee = new Employee();
				member.Employee.Id = employeeNo;
				session.Update( member, member.Id );

				member = this.GetFlowInstance.GetFlowMemberByAppStep(session, instance.Application.Id, WorkTransition.ECSCV_Close, FlowTypes.ECSCV);
				member.Employee = new Employee();
				member.Employee.Id = employeeNo;
				session.Update( member, member.Id );
				this.GetFlowInstance.SaveActionLog(session, instance.Application.Id, BEGDC.CC.BL.Workflow.Action.Reassign, instance.CurrentStep.StepCode, instance.CurrentStep.StepCode, string.Empty);
			}
		}

		[Transaction(TransactionMode.Requires)]
		public void DepartmentVPApprove(long flowID, string nextTransition, string comment)
		{
			PerformWorkflow(flowID, nextTransition, comment);
		}

		[Transaction(TransactionMode.Requires)]
		public void SSMEEVPApprove(long flowID, string nextTransition, string comment)
		{
			PerformWorkflow(flowID, nextTransition, comment);
		}

		[Transaction(TransactionMode.Requires)]
		public void CostCenterHeadApprove(long flowID, string nextTransition, string comment)
		{
			PerformWorkflow(flowID, nextTransition, comment);
		}

		[Transaction(TransactionMode.Requires)]
		public void DepartmentHeadApprove(long flowID, string nextTransition, string comment)
		{
			PerformWorkflow(flowID, nextTransition, comment);
		}

		[Transaction(TransactionMode.Requires)]
		public void DepartmentFNCApprove(long flowID, string nextTransition, string comment)
		{
			PerformWorkflow(flowID, nextTransition, comment);
		}

		[Transaction(TransactionMode.Requires)]
		public void CODApprove(long flowID, string nextTransition, string comment)
		{
			PerformWorkflow(flowID, nextTransition, comment);
		}

		[Transaction(TransactionMode.Requires)]
		public void CODVPApprove(long flowID, string nextTransition, string comment)
		{
			PerformWorkflow(flowID, nextTransition, comment);
		}

		[Transaction(TransactionMode.Requires)]
		public void Summary(long flowID, string nextTransition, string comment)
		{
			PerformWorkflow(flowID, nextTransition, comment);
		}

		[Transaction(TransactionMode.Requires)]
		public void Close(long flowID, string nextTransition, string comment)
		{
			PerformWorkflow(flowID, nextTransition, comment);
		}

		[Transaction(TransactionMode.Requires)]
		public void DrawBack(long flowID, string comment)
		{
			this.GetFlowInstance.Drawback(_sessionManager.OpenSession(), flowID, comment);
		}

		[Transaction(TransactionMode.Requires)]
		public void Query(long flowID, string activeStep, string comment)
		{
			using(ISession session = _sessionManager.OpenSession())
			{
				try
				{
					this.GetFlowInstance.Query(session, flowID, activeStep, SysDicItem.ProjectStatusFlag.QUERY, comment);
				}
				catch(Exception ex)
				{
					CCS.Utility.LogAccess.WriteErrLog( ex.StackTrace, ex.Message );throw ex;
				}
				finally
				{
					session.Close();
				}
			}
		}

		public void ReplyQuery(long flowID, string comment)
		{
			using(ISession session = _sessionManager.OpenSession())
			{
				try
				{
					this.GetFlowInstance.ReplyInquiry(session, flowID, comment);
				}
				catch(Exception ex)
				{
					CCS.Utility.LogAccess.WriteErrLog( ex.StackTrace, ex.Message );throw ex;
				}
				finally
				{
					session.Close();
				}
			}
		}

		public void Suspend(long flowID, string comment)
		{
			using(ISession session = _sessionManager.OpenSession())
			{
				try
				{
					this.GetFlowInstance.Suspend(session, flowID, comment);
				}
				catch(Exception ex)
				{
					CCS.Utility.LogAccess.WriteErrLog( ex.StackTrace, ex.Message );throw ex;
				}
				finally
				{
					session.Close();
				}
			}
		}

		public void Archive(long flowID)
		{
			using(ISession session = _sessionManager.OpenSession())
			{
				try
				{
					this.GetFlowInstance.Archive(session, flowID);
				}
				catch(Exception ex)
				{
					CCS.Utility.LogAccess.WriteErrLog( ex.StackTrace, ex.Message );throw ex;
				}
				finally
				{
					session.Close();
				}
			}
		}

		public void Resume(long flowID, string comment)
		{
			using(ISession session = _sessionManager.OpenSession())
			{
				try
				{
					this.GetFlowInstance.Resume(session, flowID, comment);
				}
				catch(Exception ex)
				{
					CCS.Utility.LogAccess.WriteErrLog( ex.StackTrace, ex.Message );throw ex;
				}
				finally
				{
					session.Close();
				}
			}
		}

		private void PerformWorkflow(long flowID, string nextTransition, string comment)
		{
			using(ISession session = _sessionManager.OpenSession())
			{
				try
				{
					this.GetFlowInstance.Perform(_sessionManager.OpenSession(), flowID, nextTransition, comment);
				}
				catch(Exception ex)
				{
					CCS.Utility.LogAccess.WriteErrLog( ex.StackTrace, ex.Message );throw ex;
				}
				finally
				{
					session.Close();
				}
			}
		}

		#region Survey
		[Transaction(TransactionMode.Requires)]
		public void SubmitSurvey(Application App, BEGDC.CC.Entity.CustomerSurvey survey,IList AnswerList)
		{
			if( App == null ) return;
	
			using(ISession session = _sessionManager.OpenSession())
			{
				try
				{
					if(survey!=null)
					{
						if(survey.Id!=0)
						{
							session.Update(survey);
						}
						else
						{
							session.Save(survey);
						}
					}

					for(int i=0;i<AnswerList.Count;i++)
					{
						BEGDC.CC.Entity.SurveyAnswer sa = AnswerList[i] as BEGDC.CC.Entity.SurveyAnswer;
						sa.CustomerSurvey = survey;
						if(sa.Id!=0)
						{
							session.Update(sa);
						}
						else
						{
							session.Save(sa);
						}
					}

					BEGDC.CC.Entity.FlowInstance flowinstance = this.GetFlowInstance.GetApplicationFlow(session, App.Id);
					this.GetFlowInstance.Perform(session, flowinstance.FlowID, BEGDC.CC.BL.Workflow.WorkTransition.Submit, string.Empty);
				}
				catch(Exception ex)
				{
					CCS.Utility.LogAccess.WriteErrLog( ex.StackTrace, ex.Message );throw ex;
				}
				finally
				{
					session.Close();
				}
			}
		}
		[Transaction(TransactionMode.Requires)]
		public void SaveSurvey(Application App, BEGDC.CC.Entity.CustomerSurvey survey,IList AnswerList)
		{
			if( App == null ) return;
	
			using(ISession session = _sessionManager.OpenSession())
			{
				try
				{
					if(survey!=null)
					{
						if(survey.Id!=0)
						{
							session.Update(survey);
						}
						else
						{
							session.Save(survey);
						}
					}

					for(int i=0;i<AnswerList.Count;i++)
					{
						BEGDC.CC.Entity.SurveyAnswer sa = AnswerList[i] as BEGDC.CC.Entity.SurveyAnswer;
						sa.CustomerSurvey = survey;
						if(sa.Id!=0)
						{
							session.Update(sa);
						}
						else
						{
							session.Save(sa);
						}
					}
				}
				catch(Exception ex)
				{
					CCS.Utility.LogAccess.WriteErrLog( ex.StackTrace, ex.Message );throw ex;
				}
				finally
				{
					session.Close();
				}
			}
		}
		#endregion 
		private string GenerateAppNo(bool isSave, Application app, bool isRequest)
		{
			int maxId;
			string year = string.Empty;
			if(app.AppNo != string.Empty)
			{
				string temp = app.AppNo;
				temp = temp.Replace("-D", string.Empty);
				BEGDC.CC.BL.Common.Query.IQuery queryService = AppContainer.Instance[ServiceConst.QueryService] as BEGDC.CC.BL.Common.Query.IQuery;
				if(isRequest)
				{
					maxId = queryService.GetMaxAppID(WorkflowTypes.ECSCV, isSave && (app.AppNo.IndexOf("-D")>0 || app.AppNo == string.Empty));
					year = DateTime.Now.Year.ToString().Substring(2);
				}
				else
				{
					year = temp.Substring(temp.Length - 7, 2);
					maxId = Convert.ToInt32(temp.Substring(temp.Length - 4));
				}
			}
			else
			{
				BEGDC.CC.BL.Common.Query.IQuery queryService = AppContainer.Instance[ServiceConst.QueryService] as BEGDC.CC.BL.Common.Query.IQuery;
				maxId = queryService.GetMaxAppID(WorkflowTypes.ECSCV, isSave && (app.AppNo.IndexOf("-D")>0 || app.AppNo == string.Empty));
				year = DateTime.Now.Year.ToString().Substring(2);
			}

			string AppNo = "";
			if(app.CostCenterCode != null && app.CostCenterCode.DicItemKey != string.Empty)
			{
				AppNo += app.CostCenterCode.DicItemKey + "-";
			}
			else
			{
				AppNo += app.DepartmentType.DicItemKey + "-";
			}
			AppNo += year+"-"+ maxId.ToString().PadLeft(4,'0');
			AppNo = "ECSCV-" + AppNo;
			if(isSave && (app.AppNo.IndexOf("-D")>0 || app.AppNo == string.Empty))
				AppNo += "-D";
			return AppNo;

		}

		public void Callback(long flowID, string comment)
		{
			using(ISession session = _sessionManager.OpenSession())
			{
				try
				{
					this.GetFlowInstance.Callback(session, flowID, comment);
				}
				catch(Exception ex)
				{
					CCS.Utility.LogAccess.WriteErrLog( ex.StackTrace, ex.Message );throw ex;
				}
				finally
				{
					session.Close();
				}
			}
		}

		public void Cancel(long flowID, string comment)
		{
			using(ISession session = _sessionManager.OpenSession())
			{
				try
				{
					this.GetFlowInstance.Cancel(session, flowID, comment);
				}
				catch(Exception ex)
				{
					CCS.Utility.LogAccess.WriteErrLog( ex.StackTrace, ex.Message );throw ex;
				}
				finally
				{
					session.Close();
				}
			}
		}

		[Transaction(TransactionMode.Requires)]
		public void SaveCloseApp(Application App, IList cost, int paymentId)
		{
			if( App == null ) return;
	
			using(ISession session = _sessionManager.OpenSession())
			{
				try
				{
					if(App.Id>0)
					{
						session.Update(App);
						session.Delete("from CostCenterRelatedCost where PaymentInfoID="+paymentId);
						for(int i=0; i<cost.Count; i++)
						{
							CostCenterRelatedCost co = (CostCenterRelatedCost)cost[i];
							session.Save(co);
						}
					}
				}
				catch(Exception ex)
				{
					CCS.Utility.LogAccess.WriteErrLog( ex.StackTrace, ex.Message );throw ex;
				}
				finally
				{
					session.Close();
				}
			}
		}

		[Transaction(TransactionMode.Requires)]
		public void CopyECSCV( int appId )
		{
			using( ISession session = _sessionManager.OpenSession() )
			{
				try
				{
					
					//GET APPLICATION-------------------------------------------------------------------------------
					Application app = session.Get(typeof(Application), appId) as Application;
					if( app == null )
						return;
					
					//CREATE NEW APPLICATION
					#region New App
					Application newapp = new Application();
					newapp.RequesterNo =  ((CCIdentity)HttpContext.Current.User.Identity).UserInfo;
					newapp.Account = app.Account;
					newapp.AllDept = app.AllDept;
					newapp.Activity = app.Activity;	
					newapp.AlternateDateFrom = app.AlternateDateFrom;	
					newapp.AlternateDateTo = app.AlternateDateTo;
					newapp.ApplicationType = app.ApplicationType;
					newapp.ApplyForSomeoneElse = app.ApplyForSomeoneElse;
					newapp.CATBranch = app.CATBranch;
					newapp.DepartmentName = app.DepartmentName;
					newapp.DepartmentType = app.DepartmentType;
					newapp.IsReviewedGuideline = app.IsReviewedGuideline;
					newapp.IsTransition = app.IsTransition;
					newapp.LGDNo = app.LGDNo;
					newapp.OtherCountry = app.OtherCountry;
					newapp.Others = app.Others;
					newapp.OtherSite = app.OtherSite;
					newapp.RequestDate = System.DateTime.Now;
					newapp.RequestedDateFrom = app.RequestedDateFrom;
					newapp.RequestedDateTo = app.RequestedDateTo;
					newapp.RequesterDept = app.RequesterDept;
					newapp.RequesterMobile = app.RequesterMobile;
					newapp.RequesterNameCN = ((CCIdentity)HttpContext.Current.User.Identity).UserInfo.NameCN;
					newapp.RequesterNameEN = ((CCIdentity)HttpContext.Current.User.Identity).UserInfo.NameEN;
					newapp.RequesterOfficeTel = app.RequesterOfficeTel;
					newapp.SomeoneElseEmail = app.SomeoneElseEmail;
					newapp.SomeoneElseHRID = app.SomeoneElseHRID;
					newapp.SomeoneElseMobil = app.SomeoneElseMobil;
					newapp.SomeoneElseNameCN = app.SomeoneElseNameCN;
					newapp.SomeoneElseNameEN = app.SomeoneElseNameEN;
					newapp.SomeoneElseNo = app.SomeoneElseNo;
					newapp.SomeoneElseTel = app.SomeoneElseTel;
					newapp.Summary = app.Summary;
					newapp.LegalEntity = app.LegalEntity;
					newapp.AppNo = string.Empty;
					
					newapp.IsSSME = app.IsSSME;
					newapp.BUHeadApproved = app.BUHeadApproved;
					newapp.CostCenterCode = app.CostCenterCode;
					newapp.NeedEVPApproval = false;
					newapp.AppNo = this.GenerateAppNo(true, newapp, false);

					session.Save(newapp);
					#endregion

					//CREATE NEW CUSTOMER
					#region New Customer
					IList CustomerList = session.Find("From CustomerInfo WHERE AppID = " + appId );
					Entity.CustomerInfo customer = null;
					if(CustomerList!=null&&CustomerList.Count>0)
					{
						customer = CustomerList[0] as CustomerInfo;
					}
					CustomerInfo newcustomer = null;
					if(customer!=null)
					{
						newcustomer= new CustomerInfo();
						newcustomer.Application = newapp;
						newcustomer.AccountType = customer.AccountType;
						newcustomer.CompanyProfile = customer.CompanyProfile;
						newcustomer.Company = customer.Company;
						newcustomer.Venue = customer.Venue;
						newcustomer.VisitObjective = customer.VisitObjective;
						newcustomer.Country = customer.Country;
						newcustomer.IsFCPA = customer.IsFCPA;
						newcustomer.IsInRFP = customer.IsInRFP;
						newcustomer.IsInRFP = customer.IsInRFP;

						newcustomer.IsKeyMessage = customer.IsKeyMessage;
						newcustomer.IsSensitiveIssue = customer.IsSensitiveIssue;
						newcustomer.IsThereSensitiveIssue = customer.IsThereSensitiveIssue;
						newcustomer.IsThereKeyMessage = customer.IsThereKeyMessage;
						newcustomer.Name = customer.Name;
						newcustomer.NumberOfPerson = customer.NumberOfPerson;
						newcustomer.PotentialRevenueTimeframe = customer.PotentialRevenueTimeframe;
						newcustomer.ProposalNo = customer.ProposalNo;
						newcustomer.RevenuePotential = customer.RevenuePotential;

						newcustomer.RFPDetail = customer.RFPDetail;
						newcustomer.SalesStage = customer.SalesStage;
						newcustomer.Title = customer.Title;
						newcustomer.Venue = customer.Venue;
						newcustomer.VisitObjective = customer.VisitObjective;
						session.Save(newcustomer);
					}
					#endregion

					//CREATE NEW BUSINESS
					#region New Business
					IList BusinessList = session.Find("From BusinessPurpose WHERE AppID = " + appId );
					Entity.BusinessPurpose business = null;
					if(BusinessList!=null&&BusinessList.Count>0)
					{
						business = BusinessList[0] as BusinessPurpose;
					}
					Entity.BusinessPurpose newbusiness = null;
					if(business!=null)
					{
						newbusiness= new BusinessPurpose();
						newbusiness.Application = newapp;
						newbusiness.IsContractSigned = business.IsContractSigned;
						newbusiness.IsInSalesContract = business.IsInSalesContract;
						newbusiness.IsNeedInvitationLetter = business.IsNeedInvitationLetter;
						newbusiness.Itinerary = business.Itinerary;
						newbusiness.Opportunities = business.Opportunities;
						newbusiness.RecreationalActivity = business.RecreationalActivity;
						session.Save(newbusiness);
					}
					#endregion

					//CREATE NEW SALES
					#region New Sales
					IList SalesList = session.Find("From SalesTeamInfo WHERE AppID = " + appId );
					Entity.SalesTeamInfo sales = null;
					if(SalesList!=null&&SalesList.Count>0)
					{
						sales = SalesList[0] as SalesTeamInfo;
					}
					Entity.SalesTeamInfo newsales = null;
					if(sales!=null)
					{
						newsales= new SalesTeamInfo();
						newsales.Application = newapp;
						newsales.Email = sales.Email;
						newsales.HostNameCN = sales.HostNameCN;
						newsales.HostNameEN = sales.HostNameEN;
						newsales.OfficeFax = sales.OfficeFax;
						newsales.OfficeTel = sales.OfficeTel;
						newsales.Region = sales.Region;
						newsales.SalesBusinessUnit = sales.SalesBusinessUnit;
						session.Save(newsales);
					}
					#endregion

					//CREATE NEW TOPIC
					#region New Topic
					IList TopicList = session.Find("From Topic WHERE AppID = " + appId );
					Entity.Topic topic = null;
					if(TopicList!=null&&TopicList.Count>0)
					{
						topic = TopicList[0] as Topic;
					}
					Entity.Topic newtopic = null;
					if(topic!=null)
					{
						newtopic= new Topic();
						newtopic.Application = newapp;
						newtopic.TopicName = topic.TopicName;
						session.Save(newtopic);
					}
					#endregion

					//CREATE NEW LOGISTIC
					#region New Logistic
					IList LogisticalList = session.Find("From LogisticalInfo WHERE AppID = " + appId );
					Entity.LogisticalInfo logistic = null;
					if(LogisticalList!=null&&LogisticalList.Count>0)
					{
						logistic = LogisticalList[0] as LogisticalInfo;
					}
					Entity.LogisticalInfo newlogistic = null;
					if(logistic!=null)
					{
						newlogistic= new LogisticalInfo();
						newlogistic.Application = newapp;
						newlogistic.ArrivalAirport = logistic.ArrivalAirport;
						newlogistic.ArrivalFlightNo = logistic.ArrivalFlightNo;
						newlogistic.ArrivalTime = logistic.ArrivalTime;
						newlogistic.AverageMealCost = logistic.AverageMealCost;
						newlogistic.CateringDescription = logistic.CateringDescription;
						newlogistic.Comment = logistic.Comment;
						newlogistic.DateRequiredFrom = logistic.DateRequiredFrom;
						newlogistic.DateRequiredTo = logistic.DateRequiredTo;
						newlogistic.DecryptedEntertainmentPriceFrom = logistic.DecryptedEntertainmentPriceFrom;
						newlogistic.DecryptedEntertainmentPriceTo = logistic.DecryptedEntertainmentPriceTo;
						newlogistic.DecryptedGiftPriceFrom = logistic.DecryptedGiftPriceFrom;
						newlogistic.DecryptedGiftPriceTo = logistic.DecryptedGiftPriceTo;
						newlogistic.DecryptedPriceFrom = logistic.DecryptedPriceFrom;
						newlogistic.DecryptedPriceTo = logistic.DecryptedPriceTo;
						newlogistic.DepartureAirport = logistic.DepartureAirport;
						newlogistic.DepartureFlightNo = logistic.DepartureFlightNo;
						newlogistic.DepartureTime = logistic.DepartureTime;
						newlogistic.Duration = logistic.Duration;
						newlogistic.EntertainmentPreference = logistic.EntertainmentPreference;

						newlogistic.GiftDetails = logistic.GiftDetails;
						newlogistic.GiftPreference = logistic.GiftPreference;
						newlogistic.HotelPreferences = logistic.HotelPreferences;
						newlogistic.InterpretionType = logistic.InterpretionType;
						newlogistic.IsMealReservation = logistic.IsMealReservation;
						newlogistic.IsNeedCatering = logistic.IsNeedCatering;
						newlogistic.IsNeedEntertainment = logistic.IsNeedEntertainment;
						newlogistic.IsNeedGift = logistic.IsNeedGift;
						newlogistic.IsNeedGroundTransportation = logistic.IsNeedGroundTransportation;
						newlogistic.IsNeedHotel = logistic.IsNeedHotel;
						newlogistic.IsNeedInterpreter = logistic.IsNeedInterpreter;
						newlogistic.IsNeedTravelAgency = logistic.IsNeedTravelAgency;
						newlogistic.IsReceivedALGiftBefore = logistic.IsReceivedALGiftBefore;
						newlogistic.Itinerary = logistic.Itinerary;
						newlogistic.MealReservation = logistic.MealReservation;
						newlogistic.MeetingRoom = logistic.MeetingRoom;
						newlogistic.ReceivedGiftDetails = logistic.ReceivedGiftDetails;
						newlogistic.SpecialDialect = logistic.SpecialDialect;
						newlogistic.TravelAgency = logistic.TravelAgency;
						session.Save(newlogistic);
					}
					#endregion

					//CREATE NEW PAYMENT
					#region New Payment
					IList PaymentList = session.Find("From PaymentInfo WHERE AppID = " + appId );
					Entity.PaymentInfo payment = null;
					if(PaymentList!=null&&PaymentList.Count>0)
					{
						payment = PaymentList[0] as PaymentInfo;
					}
					Entity.PaymentInfo newpayment = null;
					if(payment!=null)
					{
						newpayment = new PaymentInfo();
						newpayment.Application = newapp;
						newpayment.Comments = payment.Comments;
						newpayment.CustomerPerdiem = payment.CustomerPerdiem;
						newpayment.DecryptedEstimateCustomerdIndividualCost = payment.DecryptedEstimateCustomerdIndividualCost;
						newpayment.DecryptedEstimatedCustomerTotalCost = payment.DecryptedEstimatedCustomerTotalCost;
						newpayment.EstimateCustomerdIndividualCost = payment.EstimateCustomerdIndividualCost;
						newpayment.EstimatedCustomerTotalCost = payment.EstimatedCustomerTotalCost;
						newpayment.IsPayServiceProvider = payment.IsPayServiceProvider;
						newpayment.NotDirectPayReasons = payment.NotDirectPayReasons;
						newpayment.Payer = payment.Payer;
						session.Save(newpayment);
					}
					#endregion

					#region Customer List
					IList CustomerAttendeeList = null;
					if(customer!=null&&newcustomer!=null)
					{
						CustomerAttendeeList = session.Find("FROM CustomerAttendee WHERE CustomerInfoID = " + customer.Id );
						if( CustomerAttendeeList != null && CustomerAttendeeList.Count > 0 )
						{
							for( int i=0; i < CustomerAttendeeList.Count; i++ )
							{
								Entity.CustomerAttendee att = CustomerAttendeeList[i] as Entity.CustomerAttendee;
								if( att != null )
								{
									Entity.CustomerAttendee newatt = new Entity.CustomerAttendee();
									newatt.CustomerInfo = newcustomer;
									newatt.Affects = att.Affects;
									newatt.ClearDate = att.ClearDate;
									newatt.Company = att.Company;
									newatt.CompanyEN = att.CompanyEN;
									newatt.Gender = att.Gender;
									newatt.IsAttended = att.IsAttended;
									newatt.IsExisted = att.IsExisted;
									newatt.NameCN = att.NameCN;
									newatt.NameEN = att.NameEN;
									newatt.Remark = att.Remark;
									newatt.Responsibility = att.Responsibility;
									newatt.Title = att.Title;
									newatt.TitleEN = att.TitleEN;
									session.Save(newatt);
								}
							}
						}
					}
					#endregion
					
					#region AL Attendee
					//Get AL Attendee list
					IList alAttendeeList = session.Find("From ALAttendee WHERE AppID = " + appId );
					if( alAttendeeList != null && alAttendeeList.Count > 0 )
					{
						for( int i=0; i<alAttendeeList.Count; i++ )
						{
							Entity.ALAttendee attendee = alAttendeeList[i] as Entity.ALAttendee;
							if( attendee != null )
							{
								Entity.ALAttendee newalattendee = new Entity.ALAttendee();
								newalattendee.Application = newapp;
								newalattendee.ContactInfo = attendee.ContactInfo;
								newalattendee.EmployeeId = attendee.EmployeeId;
								newalattendee.Title = attendee.Title;
								session.Save(newalattendee);
							}
						}
					}
					#endregion

					#region App Visiting Site
					//Get AL Attendee list
					IList VisitingSiteList = session.Find("from AppVisitingSite where AppID=" + appId );
					if( VisitingSiteList != null && VisitingSiteList.Count > 0 )
					{
						for( int i=0; i<VisitingSiteList.Count; i++ )
						{
							Entity.AppVisitingSite site = VisitingSiteList[i] as Entity.AppVisitingSite;
							if( site != null )
							{
								Entity.AppVisitingSite newsite = new Entity.AppVisitingSite();
								newsite.Application = newapp;
								newsite.Site = site.Site;
								session.Save(newsite);
							}
						}
					}
					#endregion

					#region Cost Center Related Cost
					//Get AL Attendee list
					if(payment!=null&&newpayment!=null)
					{
						IList CostList = session.Find("from CostCenterRelatedCost where PaymentInfoID=" + payment.Id );
						if( CostList != null && CostList.Count > 0 )
						{
							for( int i=0; i<CostList.Count; i++ )
							{
								Entity.CostCenterRelatedCost cost = CostList[i] as Entity.CostCenterRelatedCost;
								if( cost != null )
								{
									Entity.CostCenterRelatedCost newcost = new Entity.CostCenterRelatedCost();
									newcost.PaymentInfo = newpayment;
									newcost.Cost = cost.Cost;
									newcost.CostCenterCode = cost.CostCenterCode;
									newcost.CostType = cost.CostType;
									newcost.DecryptedCost = cost.DecryptedCost;
									session.Save(newcost);
								}
							}
						}
					}
					#endregion

					#region Contract
					IList ContractList = session.Find("from ContractInfo where AppID=" + appId );
					if( ContractList != null && ContractList.Count > 0 )
					{
						for( int i=0; i<ContractList.Count; i++ )
						{
							Entity.ContractInfo contract = ContractList[i] as Entity.ContractInfo;
							if( contract != null )
							{
								Entity.ContractInfo newcontract = new Entity.ContractInfo();
								newcontract.Application = newapp;
								newcontract.Budget = contract.Budget;
								newcontract.ContractNo = contract.ContractNo;
								newcontract.DateOfContract = contract.DateOfContract;
								newcontract.ProducstSold = contract.ProducstSold;
								newcontract.Quotas = contract.Quotas;
								newcontract.UnitPrice = contract.UnitPrice;
								newcontract.VisitPurposeInContract = contract.VisitPurposeInContract;
								session.Save(newcontract);
							}
						}
					}
					#endregion

					#region Attachment
					//Get Attachments					
					IList attList = session.Find(" From Attachment WHERE AppID = " + appId );
					if( attList != null && attList.Count > 0 )
					{
						for( int i=0; i < attList.Count; i++ )
						{
							Entity.Attachment att = attList[i] as Attachment;
							if( att != null )
							{
								Entity.Attachment newatt = new Entity.Attachment();
								newatt.Application = newapp;
								newatt.ActionPoint = att.ActionPoint;
								newatt.AttachmentType = att.AttachmentType;
								newatt.Date = att.Date;
								newatt.FileName = att.FileName;
								newatt.FilePath = att.FilePath;
								newatt.Owner = att.Owner;
								session.Save(newatt);
							}
						}
					}
					#endregion

				}
				catch(Exception ex)
				{
					CCS.Utility.LogAccess.WriteErrLog( ex.StackTrace, ex.Message );
					throw new GDCException( ErrorCode.DB_Exception, ex.Message, ex );
				}
				finally
				{
					session.Close();
				}
			}
		}

		private void ConvertDatatableToList(DataTable dtSite, DataTable dtCustomer, DataTable dtAL, DataTable dtCost,
			DataTable dtContract, ref IList customerAttendee, ref IList alAttendee, ref IList site, ref IList cost, ref IList contract)
		{
			// site info
			if(dtSite != null && dtSite.Rows.Count > 0)
			{
				for(int i=0;i<dtSite.Rows.Count;i++)
				{
					AppVisitingSite appSite = new AppVisitingSite();
					appSite.Site = new DicItem();
					appSite.Site.Id = Convert.ToInt32(dtSite.Rows[i]["DicItemID"]);

					site.Add(appSite);
				}
			}

			// Customer Attendee Info
			if(dtCustomer != null && dtCustomer.Rows.Count > 0)
			{
				for(int i=0;i<dtCustomer.Rows.Count;i++)
				{
					CustomerAttendee cus = new CustomerAttendee();
					cus.NameEN = dtCustomer.Rows[i]["Name"].ToString();
					cus.Title = dtCustomer.Rows[i]["Title"].ToString();
					cus.Responsibility = new DicItem();
					cus.Responsibility.Id =	Convert.ToInt32(dtCustomer.Rows[i]["ResponsibilityID"]);
					cus.Affects = new DicItem();
					cus.Affects.Id = Convert.ToInt32(dtCustomer.Rows[i]["AffectsID"]);
					cus.IsAttended = true;
					cus.Remark = dtCustomer.Rows[i]["Remark"].ToString();

					customerAttendee.Add(cus);
				}
			}

			// AL Attendee Info
			if(dtAL != null && dtAL.Rows.Count > 0)
			{
				for(int i=0;i<dtAL.Rows.Count;i++)
				{
					ALAttendee al = new ALAttendee();
					al.EmployeeId = new Employee();
					al.EmployeeId.Id = dtAL.Rows[i]["EmployeeId"].ToString();
					al.Title = dtAL.Rows[i]["Title"].ToString();
		
					alAttendee.Add(al);
				}
			}

			// Cost Center Info
			if(dtCost != null && dtCost.Rows.Count > 0)
			{
				for(int i=0;i<dtCost.Rows.Count;i++)
				{
					CostCenterRelatedCost co = new CostCenterRelatedCost();
					co.CostCenterCode = dtCost.Rows[i]["CostCenterCode"].ToString();
					co.DecryptedCost = Convert.ToDecimal(dtCost.Rows[i]["Cost"]);
					co.CostType = CostType.Budget;
		
					cost.Add(co);
				}
			}

			// Contract Info
			if(dtContract != null && dtContract.Rows.Count > 0)
			{
				for(int i=0;i<dtContract.Rows.Count;i++)
				{
					ContractInfo ci = new ContractInfo();
					ci.DateOfContract = Convert.ToDateTime(dtContract.Rows[i]["DateOfContract"]);
					ci.ContractNo = dtContract.Rows[i]["ContractNo"].ToString();
					ci.ProducstSold = dtContract.Rows[i]["ProducstSold"].ToString();
					ci.VisitPurposeInContract = dtContract.Rows[i]["VisitPurposeInContract"].ToString();
					ci.Quotas = Convert.ToInt32(dtContract.Rows[i]["Quotas"]);
					ci.UnitPrice = Convert.ToDecimal(dtContract.Rows[i]["UnitPrice"]);
					ci.Budget = Convert.ToDecimal(dtContract.Rows[i]["Budget"]);
		
					contract.Add(ci);
				}
			}
			
		}

		#region Get Infomation
		[Transaction(TransactionMode.Requires)]
		public BEGDC.CC.Entity.Application GetApplication( int AppID )
		{
			IList list;
			using(ISession session = _sessionManager.OpenSession())
			{
				try
				{
					list = session.Find("From Application as app where app.Id="+AppID);
					if(list.Count>0)
					{
						BEGDC.CC.Entity.Application App = list[0] as BEGDC.CC.Entity.Application;
						return App;
					}
					else
					{
						return null;
					}
				}
				catch(Exception ex)
				{
					CCS.Utility.LogAccess.WriteErrLog( ex.StackTrace, ex.Message );throw ex;
				}
				finally
				{
					session.Close();
				}	
			}
		}
		[Transaction(TransactionMode.Requires)]
		public BEGDC.CC.Entity.CustomerSurvey GetCustomerSurvey( int AppID )
		{
			IList CtInfo = null;
			using(ISession session = _sessionManager.OpenSession())
			{
				try
				{
					CtInfo = session.Find("From CustomerSurvey as cs where cs.Application.Id="+AppID);
					if(CtInfo!=null&&CtInfo.Count>0)
					{
						//Get Customer Info
						BEGDC.CC.Entity.CustomerSurvey survey = CtInfo[0] as BEGDC.CC.Entity.CustomerSurvey;

						return survey;
					}
					else
					{
						return null;
					}
				}
				catch(Exception ex)
				{
					CCS.Utility.LogAccess.WriteErrLog( ex.StackTrace, ex.Message );throw ex;
				}
				finally
				{
					session.Close();
				}	
			}
		}
		[Transaction(TransactionMode.Requires)]
		public BEGDC.CC.Entity.LogisticalInfo GetLogisticalInfo( int AppID )
		{
			IList list;
			using(ISession session = _sessionManager.OpenSession())
			{
				try
				{
					list = session.Find("From LogisticalInfo as log where log.Application.Id="+AppID);
					if(list!=null&&list.Count>0)
					{
						BEGDC.CC.Entity.LogisticalInfo log = list[0] as BEGDC.CC.Entity.LogisticalInfo;
						return log;
					}
					else
					{
						return null;
					}
				}
				catch(Exception ex)
				{
					CCS.Utility.LogAccess.WriteErrLog( ex.StackTrace, ex.Message );throw ex;
				}
				finally
				{
					session.Close();
				}	
			}
		}
		[Transaction(TransactionMode.Requires)]
		public DataTable GetSurveyQuestions(string appType, string Type, bool Enable)
		{
			using(ISession session = _sessionManager.OpenSession())
			{
				try
				{
					string EnableStr = " and sq.isEnable='1' ";
					string sql = "";
					if(Enable)
					{
						sql = "Select sq.QuestionID AS Id, sq.Question AS Question, sq.Type AS Type, sq.Sort AS Sort, sq.isEnable AS Enable From SurveyQuestion AS sq where sq.Type='"+Type+"' "+EnableStr+" and applicationtype='" + appType + "'order by sq.Sort";
					}
					else
					{
						sql = "Select sq.QuestionID AS Id, sq.Question AS Question, sq.Type AS Type, sq.Sort AS Sort, sq.isEnable AS Enable From SurveyQuestion AS sq where sq.Type='"+Type+"' and applicationtype='" + appType + "' order by sq.Sort";
					}
					return BEGDC.Utility.NHibernate.NHibernateUtil.Execute(session, sql);
				}
				catch(Exception ex)
				{
					CCS.Utility.LogAccess.WriteErrLog( ex.StackTrace, ex.Message );throw ex;
				}
				finally
				{
					session.Close();
				}	
			}
		}
		[Transaction(TransactionMode.Requires)]
		public DataTable GetSurveyAnswer( int SurveyId )
		{
			using(ISession session = _sessionManager.OpenSession())
			{
				try
				{
					string sql = "Select sa.QuestionID AS QuestionId, sa.Score AS Score, sa.Comment AS Comment From SurveyAnswer AS sa where sa.CustomerSurveyID="+SurveyId;
					return BEGDC.Utility.NHibernate.NHibernateUtil.Execute(session, sql);
				}
				catch(Exception ex)
				{
					CCS.Utility.LogAccess.WriteErrLog( ex.StackTrace, ex.Message );throw ex;
				}
				finally
				{
					session.Close();
				}	
			}
		}
		[Transaction(TransactionMode.Requires)]
		public IList GetSurveyAnswerList( int SurveyId )
		{
			IList AnswerList = null;
			using(ISession session = _sessionManager.OpenSession())
			{
				try
				{
					AnswerList = session.Find("From SurveyAnswer as sa where sa.CustomerSurvey.Id="+SurveyId);
					if(AnswerList!=null&&AnswerList.Count>0)
					{
						return AnswerList;
					}
					else
					{
						return null;
					}
				}
				catch(Exception ex)
				{
					CCS.Utility.LogAccess.WriteErrLog( ex.StackTrace, ex.Message );throw ex;
				}
				finally
				{
					session.Close();
				}		
			}
		}
		[Transaction(TransactionMode.Requires)]
		public IList GetSurveyQuestionList()
		{
			IList QList = null;
			using(ISession session = _sessionManager.OpenSession())
			{
				try
				{
					QList = session.Find("From SurveyQuestion");
					if(QList!=null&&QList.Count>0)
					{
						return QList;
					}
					else
					{
						return null;
					}
				}
				catch(Exception ex)
				{
					CCS.Utility.LogAccess.WriteErrLog( ex.StackTrace, ex.Message );throw ex;
				}
				finally
				{
					session.Close();
				}		
			}
		}
		#endregion
	}
}
